﻿/*****************************************************************************
* Project:
* All project
* Copyright (C) 2008-2018, shenju Ltd.
* All Rights Reserved.
* Description:
* All code is genrated by shenju-yangyang
* Author:
* yangyang
****************************************************************************/
#include <windows.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "cmdline.h"

#define MAX_COMMANDS 100
static struct {
    int input_enabled;
    int initialized;

    unsigned int bp;
    char* inbuf;

    const struct OAL_cliCommand* commands[MAX_COMMANDS];
    unsigned int num_commands;
    int echo_disabled;
} cli;

int OAL_cliStart()
{
    int n = 0;
    char* scan_buf[10];
    char scan_line[1024];

    for (n = 0; n < 10; n++)
    {
        scan_buf[n] = malloc(MAX_PATH);
    }

    while (1)
    {
        printf("# ");
        if (fgets(scan_line, 1024, stdin))
        {
            int i = 0, j = 0;
            int index = 0;
            char argStartWithYinHao = 0;
            for (n = 0; n < 10; n++)
            {
                memset(scan_buf[n], 0, MAX_PATH);
            }

            while (scan_line[i] != L'\n')
            {
                if (scan_line[i] == L'"')
                {
                    if (argStartWithYinHao == 1)
                        argStartWithYinHao = 2;
                    else
                    {
                        argStartWithYinHao = 1;
                        i++;
                    }
                }
                if ((scan_line[i] == L' ' && argStartWithYinHao == 0)
                    || argStartWithYinHao == 2)
                {
                    scan_buf[index][j] = 0;
                    index++;
                    j = 0;
                    i++;
                    argStartWithYinHao = 0;
                    continue;
                }
                scan_buf[index][j] = scan_line[i];
                j++;
                i++;
            }

            i = 0;
            while (cli.commands[i] != NULL)
            {
                if (strcmp(cli.commands[i]->name, scan_buf[0]) == 0)
                {
                    cli.commands[i]->function(index + 1, scan_buf);
                    break;
                }
                i++;
            }
            if (strcmp("exit", scan_buf[0]) == 0)
            {
                break;
            }
            if (cli.commands[i] == NULL && strlen(scan_buf[0]) != 0)
                printf("Bad command or not registed command.\r\n");
        }
    }
    for (n = 0; n < 10; n++)
    {
        free(scan_buf[n]);
    }

    return 0;
}

static int cliRegisterCommand(const struct OAL_cliCommand* command)
{
    unsigned int i;
    if (!command->name || !command->function)
        return 1;

    if (cli.num_commands < MAX_COMMANDS) {
        // Check if the command has already been registered.
        // Return 0, if it has been registered.

        for (i = 0; i < cli.num_commands; i++) {
            if (cli.commands[i] == command)
                return 0;
        }
        cli.commands[cli.num_commands++] = command;
        return 0;
    }

    return 1;
}
int OAL_cliRegisterCommands(const struct OAL_cliCommand* commands, int num_commands)
{
    int i;
    for (i = 0; i < num_commands; i++)
        if (cliRegisterCommand(commands++))
            return 1;
    return 0;
}

static void cmd_line_showhelp(int argc, char* argv[])
{
    int i = 0;

    while (cli.commands[i] != NULL)
    {
        printf("%s %s\r\n", cli.commands[i]->name, cli.commands[i]->help);
        i++;
    }
}
struct OAL_cliCommand oal_cmdline_commands[] = {
    // {command_name, Command info, handler function}
    { "help", "", cmd_line_showhelp },
    { 0,0,0 },
};

int OAL_cliInit()
{
    int ret;
    memset((void*)&cli, 0, sizeof(cli));
    ret = 0; while (oal_cmdline_commands[ret].name != 0)ret++;
    OAL_cliRegisterCommands(oal_cmdline_commands, ret);

    return 0;
}
